﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;

using System.Data;
using Warensoft.Unity.Communication.Client.DataClient;
using Warensoft.Unity.Communication.Client.Contracts;
#if SERVER
namespace Warensoft.DataService.Models
#else
namespace Warensoft.Unity.Communication.Client.Models
#endif

{
    public static class Extension
    {
        public static byte[] ToArray(this Dictionary<string, object> dic)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, dic);
            var result = ms.ToArray();
            ms.Close();
            return result;

        }
        public static Dictionary<string, object> ToDictionary(this byte[] buffer)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream(buffer);
            var result = bf.Deserialize(ms) as Dictionary<string, object>;
            ms.Close();
            return result;
        }
        public static byte[] ToArray(this DataSet ds)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, ds);
            var buffer = ms.ToArray();
            ms.Close();
            var outBuffer = System.Text.Encoding.UTF8.GetBytes(Convert.ToBase64String(buffer));
            return outBuffer;
        }
        public static DataSet ToDataSet(this byte[] buffer)
        {
            var xmlBuffer = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(buffer));
            string text = System.Text.Encoding.UTF8.GetString(xmlBuffer);

            MemoryStream ms = new MemoryStream(xmlBuffer);
            //ds.ReadXml(ms, XmlReadMode.ReadSchema);
            BinaryFormatter bf = new BinaryFormatter();
            var ds = bf.Deserialize(ms) as DataSet;
            ms.Close();
            return ds;
        }
        public static byte[] ToByteArray(this List<DataEntity> entities)
        {
            byte[] buffer = null;
            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write(entities.Count);
                    foreach (var item in entities)
                    {
                        var entityBuffer = item.ToArray();
                        bw.Write(entityBuffer.Length);
                        bw.Write(entityBuffer, 0, entityBuffer.Length);
                    }
                }
                buffer = ms.ToArray();
            }
            return buffer;
        }
        public static List<DataEntity> ToDataEntityList(this byte[] buffer)
        {
            List<DataEntity> result = new List<DataEntity>();
            using (MemoryStream ms = new MemoryStream(buffer))
            {
                using (BinaryReader br = new BinaryReader(ms))
                {
                    int count = br.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        int entityBufferLength = br.ReadInt32();
                        byte[] entityBuffer = new byte[entityBufferLength];
                        br.Read(entityBuffer, 0, entityBuffer.Length);
                        DataEntity entity = DataEntity.Create(entityBuffer);
                        result.Add(entity);
                    }
                }
            }
            return result;
        }
    }
    [Serializable]
    public class DataServicePackage:IMessage,IResponseMessage
    {
        public string Command { get; set; }
        public string CommandText { get; set; }
        public ResultInfo Result { get; set; }
        public Guid ID { get; set; }
        public Warensoft.Unity .Communication.Client. RefreshMode RefreshMode { get; set; }
        public DataServicePackage()
        {
            this.Command = "";
            this.CommandText = "";
            this.ID = Guid.Empty;
            this.RefreshMode = Warensoft.Unity .Communication .Client .RefreshMode.StoreWins;
            
        }
        public static DataServicePackage Create(byte[] buffer)
        {
            buffer = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(buffer));
            MemoryStream ms = new MemoryStream(buffer);
            BinaryReader br = new BinaryReader(ms);
            DataServicePackage result = new DataServicePackage();

            result.Command = br.ReadString();
            result.CommandText = br.ReadString();
            result.ID = new Guid(br.ReadString());
            result.RefreshMode = (Warensoft.Unity.Communication.Client.RefreshMode)br.ReadByte();

            int length = br.ReadInt32();
            if (length != 0)
            {
                byte[] resultBuffer = new byte[length];
                br.Read(resultBuffer, 0, length);
                result.Result = ResultInfo.Create(resultBuffer);
            }

            ms.Close();
            br.Close();
            buffer = null;
            return result;
        }
        public byte[] ToArray()
        {

            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);
            bw.Write(this.Command);
            bw.Write(this.CommandText);
            bw.Write(this.ID.ToString());
            bw.Write((byte)this.RefreshMode );

            if (this.Result == null)
            {
                bw.Write((int)0);
            }
            else
            {
                var resultBuffer = this.Result.ToArray();
                bw.Write(resultBuffer.Length);
                bw.Write(resultBuffer);
            }

            var buffer = ms.ToArray();
            buffer = System.Text.Encoding.UTF8.GetBytes(Convert.ToBase64String(buffer));
            ms.Close();
            bw.Close();
            return buffer;
        }

        public void FillData(byte[] buffer)
        {
            buffer = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(buffer));
            MemoryStream ms = new MemoryStream(buffer);
            BinaryReader br = new BinaryReader(ms);
            DataServicePackage result = new DataServicePackage();

            this.Command = br.ReadString();
            this.CommandText = br.ReadString();
            this.ID = new Guid(br.ReadString());
            this.RefreshMode = (Warensoft.Unity.Communication.Client.RefreshMode)br.ReadByte();

            int length = br.ReadInt32();
            if (length != 0)
            {
                byte[] resultBuffer = new byte[length];
                br.Read(resultBuffer, 0, length);
                this.Result = ResultInfo.Create(resultBuffer);
            }
            buffer = null;
            ms.Close();
            br.Close();
        }
    }
}
